home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
awe2-0_1.lha
/
awe2-0.1
/
Src
/
Facility.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-09
|
7KB
|
357 lines
// This may look like C code, but it is really -*- C++ -*-
//
// Copyright (C) 1988 University of Illinois, Urbana, Illinois
// Copyright (C) 1989 University of Colorado, Boulder, Colorado
// Copyright (C) 1990 University of Colorado, Boulder, Colorado
//
// written by Dirk Grunwald (grunwald@foobar.colorado.edu)
//
#include "SimulationMultiplexor.h"
#include "Facility.h"
#include "FifoScheduler.h"
#include "Thread.h"
#include "assert.h"
#include <math.h>
Facility::Facility(int xservers, ThreadContainer *xscheduler)
: (xservers,xscheduler)
{
//
// Can't use reset because we need to set up service times with
// NullTime value.
//
servers = xservers;
totalServiceTime = 0.0;
pTotalReserves = 0;
pTotalFailures = 0;
pTotalDelay = 0.0;
serviceStarted = CurrentSimulatedTime;
if (servers == 1) {
whenServiced.single = NullTime;
} else {
whenServiced.many = new double[servers];
for (int i = 0; i < servers; i++) {
whenServiced.many[i] = NullTime;
}
}
}
//
// To reset a facility, we assume that there has been no service
// so far (totalServiceTime = 0) and then set the beginning of
// outstanding service intervals to be now.
//
// Thus, right after being reset, a facility has a utilization of zero.
//
void
Facility::reset()
{
dataLock.reserve();
double now = CurrentSimulatedTime;
totalServiceTime = 0.0;
pTotalReserves = 0;
pTotalFailures = 0;
pTotalDelay = 0.0;
serviceStarted = now;
if (servers == 1) {
if (whenServiced.single != NullTime) {
whenServiced.single = now;
}
} else {
for (int i = 0; i < servers; i++) {
if (whenServiced.many[i] != NullTime) {
whenServiced.many[i] = now;
}
}
}
dataLock.release();
}
Facility::~Facility()
{
dataLock.reserve();
int error = 0;
if (servers == 1) {
error = (whenServiced.single != NullTime);
} else {
for(int i = 0; i < servers; i++) {
error |= (whenServiced.many[i] != NullTime);
}
}
if (error) {
cerr << "[Facility:~Facility]";
cerr << "Attempted to de-allocate reserved facility\n";
// cerr << *this;
exit(1);
}
dataLock.release();
}
void Facility::commonReserve(double delayTime)
{
dataLock.reserve();
pTotalReserves++;
pTotalDelay += delayTime;
if (servers == 1) {
if (whenServiced.single == NullTime) {
whenServiced.single = CurrentSimulatedTime;
dataLock.release();
return;
}
} else {
for (int i = 0; i < servers; i++) {
if (whenServiced.many[i] == NullTime) {
whenServiced.many[i] = CurrentSimulatedTime;
dataLock.release();
return;
}
}
}
dataLock.release(); // need to release so reportErrorState works
reportErrorState(cerr);
assert2(FALSE, "[Facility] state error with facility semaphore");
}
void Facility::reserve()
{
double startedReserve = CurrentSimulatedTime;
Semaphore::reserve();
commonReserve( CurrentSimulatedTime - startedReserve );
}
void
Facility::use(double howLong)
{
reserve();
hold(howLong);
release();
}
bool Facility::reserveNoBlock()
{
if (Semaphore::reserveNoBlock()) {
commonReserve(0.0); // commonReserve will bumb pTotalReserves
return(TRUE);
} else {
dataLock.reserve();
pTotalFailures++;
dataLock.release();
return(FALSE);
}
}
void Facility::release()
{
dataLock.reserve();
double now = CurrentSimulatedTime;
bool error = 0;
if (servers == 1) {
if (whenServiced.single != NullTime) {
totalServiceTime += (now - whenServiced.single);
whenServiced.single = NullTime;
} else {
error = 1;
}
} else {
error = 1;
for (int i = 0; i < servers; i++) {
if (whenServiced.many[i] != NullTime) {
totalServiceTime += (now - whenServiced.many[i]);
whenServiced.many[i] = NullTime;
error = 0;
break;
}
}
}
dataLock.release();
if (error) {
cerr << "[Facility::release] ";
cerr << "Attempt to release un-reserved facility\n";
// cerr << *this;
exit(1);
}
Semaphore::release();
}
double Facility::utilization()
{
//
// To compute utilization, we sum the outstanding request times,
// add in the current total service time, and divide this by
// the number of facilities & the number servers.
//
dataLock.reserve();
double totalTime = totalServiceTime;
double now = CurrentSimulatedTime;
if (servers == 1) {
if (whenServiced.single != NullTime) {
totalTime += (now - whenServiced.single);
}
} else {
for (int i = 0; i < servers; i++) {
if (whenServiced.many[i] != NullTime) {
totalTime += (now - whenServiced.many[i]);
}
}
}
if (now == serviceStarted) {
totalTime = 0;
} else {
totalTime /= (servers * (now - serviceStarted));
}
dataLock.release();
return(totalTime);
}
double
Facility::perceivedUtilization()
{
dataLock.reserve();
double util = 0;
long pTotal = pTotalReserves + pTotalFailures;
if ( pTotal >0 ) {
util = pTotalFailures;
util /= pTotal;
}
dataLock.release();
return( util );
}
long
Facility::totalAttempts()
{
dataLock.reserve();
int res = pTotalReserves + pTotalFailures;
dataLock.release();
return(res);
}
long
Facility::totalReserves()
{
dataLock.reserve();
int res = pTotalReserves;
dataLock.release();
return(res);
}
long
Facility::totalFailures()
{
dataLock.reserve();
int res = pTotalFailures;
dataLock.release();
return(res);
}
double
Facility::totalDelay()
{
return(pTotalDelay);
}
double
Facility::meanDelay()
{
if (pTotalReserves > 0) {
return( pTotalDelay / pTotalReserves);
} else {
return( 0.0 );
}
}
unsigned Facility::queueLength()
{
return(Semaphore::size());
}
unsigned Facility::activeServers()
{
dataLock.reserve();
int outStanding = 0;
if (servers == 1) {
if (whenServiced.single != NullTime) {
outStanding++;
}
} else {
for (int i = 0; i < servers; i++ ){
if (whenServiced.many[i] != NullTime) {
outStanding++;
}
}
}
dataLock.release();
return(outStanding);
}
unsigned Facility::size()
{
return(queueLength() + activeServers());
}
bool Facility::isEmpty()
{
return(size() == 0);
}
#ifdef UNDEF
void Facility::classPrintOn(ostream &out)
{
out << "Facility with " << activeServers() << " active servers and "
<< queueLength() << " queued requests";
}
#endif
void Facility::reportErrorState(ostream &out)
{
// out << *this << "\n";
out << "Serviced started at " << serviceStarted
<< " with a total service time of " << totalServiceTime << "\n";
if (servers == 1) {
out << "Server 1 ";
if (whenServiced.single == NullTime) {
out << " is idle\n";
} else {
out << " started serving at " << whenServiced.single << "\n";
}
} else {
for (int i = 0; i < servers; i++) {
out << "Server " << i ;
if (whenServiced.many[i] == NullTime) {
out << " is idle\n";
} else {
out << " started serving at " << whenServiced.many[i] << "\n";
}
}
}
out << "State of facility semaphore is:\n";
// Semaphore::classPrintOn(out);
}